package com.woniu.servicepay.util;

import lombok.extern.log4j.Log4j2;
import org.springframework.boot.configurationprocessor.json.JSONObject;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Log4j2
public class PaymentWebSocketHandler extends TextWebSocketHandler {
    private static final ConcurrentHashMap<String, WebSocketSession> sessions = new ConcurrentHashMap<>();
    private static final long SESSION_TIMEOUT_MS = 30 * 60 * 1000; // 30分钟

    /**
     * 连接建立
     * @param session
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) {
        sessions.put(session.getId(), session);
        log.info("客户端连接: " + session.getId());
        // 启动30分钟后关闭连接的定时任务
        scheduleSessionClose(session, SESSION_TIMEOUT_MS);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) {
        String payload = message.getPayload();
        if ("{\"type\":\"heartbeat\"}".equals(payload)) {
            // 响应心跳
            try {
                session.sendMessage(new TextMessage("{\"type\":\"heartbeat\", \"status\":\"alive\"}"));
            } catch (IOException e) {
                log.error("心跳响应失败: " + e.getMessage());
            }
            return;
        }
        log.info("收到客户端消息: " + payload);
        // 可处理前端发送的消息
        log.info("收到客户端消息: " + message.getPayload());
    }

    /**
     * 提供给Controller调用的发送方法
     * @param params 支付回调信息
     */
    public static void sendPaymentNotification(Map<String, String> params) {
        String json = new JSONObject(params).toString();
        sessions.forEach((id, session) -> {
            try {
                if (!session.isOpen()) {
                    log.info("会话已关闭: " + id);
                    sessions.remove(id); // 清理已关闭的会话
                    return;
                }else if (session.isOpen()) {
                    session.sendMessage(new TextMessage(json));
                    log.info("已推送消息给: " + id);
                    //推送消息给前端后启动一个线程，5秒后关闭连接
                    scheduleSessionClose(session, 5000);
                }
            } catch (IOException e) {
                log.error("推送失败: " + e.getMessage());
            }
        });
    }

    /**
     * 关闭会话
     * @param session
     * @param delayMillis
     */
    private static void scheduleSessionClose(WebSocketSession session, long delayMillis) {
        new Thread(() -> {
            try {
                Thread.sleep(delayMillis);
                if (session.isOpen()) {
                    session.close();
                    sessions.remove(session.getId());
                    log.info("已关闭连接: " + session.getId());
                }
            } catch (Exception e) {
                log.error("关闭连接异常: " + e.getMessage());
            }
        }).start();
    }

}